#include "ccalwindow.h"

#include "cdayview.h"
#include "cmonthview.h"
#include "ccontrolbar.h"
#include "cminimonthview.h"

#include "ccalapp.h"

#include <buola/algorithm/container.h>
#include <buola/gui/cmenu.h>
#include <buola/widgets/ceditbox.h>
#include <buola/io/cfile.h>
#include <buola/io/cfilefilter.h>
#include <buola/widgets/cstatusbar.h>
#include <buola/widgets/ctoolbar.h>
#include <buola/widgets/cmenubar.h>
#include <buola/widgets/ctheme.h>
#include <buola/widgets/clistbox.h>
#include <buola/datetime/cdatetime.h>
#include <buola/image/cgc.h>
#include <buola/image/csurface.h>
#include <buola/image/cpattern.h>
#include <buola/image/cimagegc.h>

namespace buola { namespace bcal {

CCalWindow::CCalWindow(CCalManager *pManager)
    :   mManager(pManager),
        mViewType(VIEW_NONE)
{
    SetTitle(L"calendar");
    SetIcon(gui::CIcon::Get("kontact"));

    mStatusBar=new gui::CStatusBar;
    mStatusBar->AddItem(L"0/0",nullptr,1);

    mControlBar=new CControlBar;
    mControlBar->sChangeView.Connect(&CCalWindow::SetView,this,_1);

    mViewWindow=new CWindow;

    mCalendarList=new gui::CListBox;
    mCalendarList->Resize({200,200});
    mCalendarList->SetStyle(gui::CListBox::STYLE_GROUPVIEW);
    mCalendarList->SetIconSize(gui::CIcon::SMALLEST);
    mCalendarList->SetBackColor(img::CColor(0.84,0.87,0.90));

    mCalendarList->AddGroup(L"NETWORK");
    mCalendarList->AddGroup(L"ON THIS COMPUTER");
    mCalendarList->AddGroup(L"FILES");

    mMiniView=new CMiniMonthView(mManager);
    mMiniView->Resize({200,200});
    mMiniView->SetDate(CDate(CCalendarClock::now()));

    SetView(VIEW_DAY);

//    Attach(mStatusBar,gui::ATTACH_SOUTH,gui::ATTACH_STATUSBAR);
    Attach(mViewWindow,gui::ATTACH_REPLACECLIENT);
    Attach(mControlBar,gui::ATTACH_NORTH);
    Attach(mCalendarList,gui::ATTACH_WEST);
    Attach(mMiniView,gui::ATTACH_SOUTH_OF,mCalendarList);

    for(auto i=mManager->GetCalendars().begin();i!=mManager->GetCalendars().end();++i)
    {
        OnCalendarAdded(*i);
    }

    mManager->sCalendarAdded.Connect(&CCalWindow::OnCalendarAdded,this,_1);
}

CCalWindow::~CCalWindow()
{
}

void CCalWindow::SetView(int pViewType)
{
    if(mViewType==pViewType) return;

    mViewType=pViewType;

    if(mViewType==VIEW_DAY)
    {
        PDayView lView=new CDayView(mManager);
        lView->sChangeTitle.Connect(&CControlBar::SetCaption,mControlBar.get(),_1);
        mControlBar->sPrevious.Connect(&CDayView::Previous,lView);
        mControlBar->sNext.Connect(&CDayView::Next,lView);
        mControlBar->sToday.Connect(&CDayView::SetToday,lView);

        lView->SetDate(CDate(CCalendarClock::now()));

        mViewWindow->Attach(lView,gui::ATTACH_REPLACECLIENT);
        lView->Show();

        mCurrentView=lView;
    }
    else if(mViewType==VIEW_WEEK)
    {
        PDayView lView=new CDayView(mManager,7);
        lView->sChangeTitle.Connect(&CControlBar::SetCaption,mControlBar.get(),_1);
        mControlBar->sPrevious.Connect(&CDayView::Previous,lView);
        mControlBar->sNext.Connect(&CDayView::Next,lView);
        mControlBar->sToday.Connect(&CDayView::SetToday,lView);

        lView->SetDate(CDate(CCalendarClock::now()));

        mViewWindow->Attach(lView,gui::ATTACH_REPLACECLIENT);
        lView->Show();

        mCurrentView=lView;
    }
    else if(mViewType==VIEW_MONTH)
    {
        PMonthView lView=new CMonthView(mManager);
        lView->sChangeTitle.Connect(&CControlBar::SetCaption,mControlBar.get(),_1);
        mControlBar->sPrevious.Connect(&CMonthView::Previous,lView);
        mControlBar->sNext.Connect(&CMonthView::Next,lView);
        mControlBar->sToday.Connect(&CMonthView::SetToday,lView);

        lView->SetDate(CDate(CCalendarClock::now()));

        mViewWindow->Attach(lView,gui::ATTACH_REPLACECLIENT);
        lView->Show();

        mCurrentView=lView;
    }
}

void CCalWindow::OnCalendarAdded(CCalendar *pCalendar)
{
    gui::CListBox::SItem *lItem=mCalendarList->AddItem(pCalendar->GetName(),nullptr);

    switch(pCalendar->GetType())
    {
    case CCalendar::TYPE_LOCAL:
        lItem->SetGroup(L"ON THIS COMPUTER");
        break;
    case CCalendar::TYPE_FILE:
        lItem->SetGroup(L"FILES");
        break;
    case CCalendar::TYPE_NETWORK:
        lItem->SetGroup(L"NETWORK");
        break;
    default:
        break;
    }

    img::CImage_rgb8 lImage({16,16},img::CColor(0.84,0.87,0.90));
    img::CImageGC<img::TFormat_rgb8> lGC(lImage);

    lGC.SetSource(img::CColor(0.0,0.0,0.0,0.0));
    lGC.SetOperator(img::ECompOp::SRC);
    lGC.Paint();

    img::CColor lColor=pCalendar->GetColor();

    img::CLinearGradient lGradient({0,0},{16,16});

    lGradient.AddStop(lColor*0.4+img::CColor(0.6,0.6,0.6,0.6),0.0);
    lGradient.AddStop(lColor*0.2+img::CColor(0.8,0.8,0.8,0.8),1.0);

    lGC.Path().RoundRect(CRect_d(1.5,1.5,14.5,14.5),3);

    lGC.SetSource(lGradient);
    lGC.FillPath(true);

    lGC.SetLineWidth(1.0);
    lGC.SetSource(lColor);
    lGC.StrokePath();

    lItem->SetImage(std::move(lImage));
}

/*namespace buola*/ } /*namespace bcal*/ }
